package com.yuke.cloud.service.uac.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.yuke.cloud.common.base.constant.GlobalConstant;
import com.yuke.cloud.common.base.dto.LoginAuthDto;
import com.yuke.cloud.common.base.enums.ErrorCodeEnum;
import com.yuke.cloud.common.core.support.BaseService;
import com.yuke.cloud.common.util.PublicUtil;
import com.yuke.cloud.service.api.uac.exceptions.UacBizException;
import com.yuke.cloud.service.uac.dao.AccPermissionMapper;
import com.yuke.cloud.service.uac.dto.PermissionMainQueryDto;
import com.yuke.cloud.service.uac.entity.AccMenu;
import com.yuke.cloud.service.uac.entity.AccPermission;
import com.yuke.cloud.service.uac.service.AccPermissionService;
import com.yuke.cloud.service.uac.service.AccRolePermissionService;
import com.yuke.cloud.service.uac.service.AccUserRoleService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.AntPathMatcher;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;


/**
 * Created by wg on 2018/09/15.
 */
@Service
@Transactional
public class AccPermissionServiceImpl extends BaseService<AccPermission> implements AccPermissionService {
    @Resource
    private AccPermissionMapper accPermissionMapper;
    @Resource
    private AccRolePermissionService accRolePermissionService;
    @Resource
    private AccUserRoleService accUserRoleService;

    private AntPathMatcher antPathMatcher = new AntPathMatcher();

    @Override
    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public PageInfo queryPermissionListWithPage(PermissionMainQueryDto permissionMainQueryDto) {
        List<Long> menuIdList = permissionMainQueryDto.getMenuIdList();
        Long menuId = null;
        if (PublicUtil.isNotEmpty(menuIdList)) {
            menuId = menuIdList.get(menuIdList.size() - 1);
        }
        AccPermission accPermission = new AccPermission();
        accPermission.setMenuId(menuId);
        BeanUtils.copyProperties(permissionMainQueryDto, accPermission);
        accPermission.setOrderBy("update_time desc");
        PageHelper.startPage(permissionMainQueryDto.getPageNum(), permissionMainQueryDto.getPageSize());
        List<AccPermission> permiddionList = accPermissionMapper.queryPermissionListWithPage(accPermission);
        return new PageInfo<>(permiddionList);
    }

    @Override
    public void savePermission(AccPermission accPermission, LoginAuthDto loginAuthDto) {

        if (null == accPermission.getPermissionId()) {
            List<Long> menuIdList = accPermission.getMenuIdList();
            Long menuId;
            Preconditions.checkArgument(PublicUtil.isNotEmpty(menuIdList), "菜单名称不能为空");
            menuId = menuIdList.get(menuIdList.size() - 1);
            accPermission.setMenuId(menuId);
            Long permissionId = super.generateId();
            accPermission.setPermissionId(permissionId);
            accPermission.setCreateId(loginAuthDto.getUserId());
            accPermission.setCreateTime(new Date());
            accPermissionMapper.insertSelective(accPermission);
        } else {
            Long menuId = accPermission.getMenuId();
            Preconditions.checkArgument(menuId != null && menuId > 0L, "菜单名称不能为空");
            accPermission.setMenuId(menuId);
            accPermission.setUpdateId(loginAuthDto.getUserId());
            accPermission.setUpdateTime(new Date());
            int result = accPermissionMapper.updateByPrimaryKeySelective(accPermission);
            if (result < 1) {
                throw new UacBizException(ErrorCodeEnum.UAC10014003);
            }
        }
    }

    @Override
    public int deletePermissionById(Long permissionId) {
        //查询该角色下是否有用户绑定, 有的话提醒不能删除
        if (null == permissionId) {
            throw new IllegalArgumentException("权限ID不能为空");
        }

        AccPermission accPermission = accPermissionMapper.selectByPrimaryKey(permissionId);
        if (accPermission == null) {
            logger.error("找不到权限信息 actionId={}", permissionId);
            throw new UacBizException(ErrorCodeEnum.UAC10014001, permissionId);
        }

        // 删除角色权限表数据  不查询了 直接删除了
        accRolePermissionService.deleteByPermissionId(permissionId);

        return accPermissionMapper.deleteByPrimaryKey(permissionId);
    }

    @Override
    public int batchDeleteByIdList(List<Long> deleteIdList) {
        logger.info("批量删除角色. deleteIdList={}", deleteIdList);
        Preconditions.checkArgument(PublicUtil.isNotEmpty(deleteIdList), "删除权限ID不能为空");

        //先删除角色权限表
        accRolePermissionService.batchDeleteByPermissionIdList(deleteIdList);

        int result = accPermissionMapper.batchDeleteByIdList(deleteIdList);
        if (result < deleteIdList.size()) {
            throw new UacBizException(ErrorCodeEnum.UAC10014002, Joiner.on(GlobalConstant.Symbol.COMMA).join(deleteIdList));
        }

        return result;
    }

    @Override
    public List<AccPermission> getOwnPermissionListByUserId(Long userId) {
        if (userId == null) {
            throw new UacBizException(ErrorCodeEnum.UAC10011001);
        }
        List<AccPermission> accPermissionList;
        // mod by wg 20181220 如果用户是超级管理员，则也获取全部权限,增加|| accUserRoleService.checkAdminByUserId(userId)条件
        if (Objects.equals(userId, GlobalConstant.Sys.SUPER_MANAGER_USER_ID) || accUserRoleService.checkAdminByUserId(userId)) {
            // 获取全部权限信息
            accPermissionList = accPermissionMapper.selectAll();
        } else {
            accPermissionList = accPermissionMapper.getOwnPermissionListByUserId(userId);
        }

        return accPermissionList;
    }

    @Override
    public AccPermission matchesByUrl(String requestUrl) {
        List<AccPermission> accPermissionList = accPermissionMapper.selectAll();
        for (AccPermission accPermission : accPermissionList) {
            String url = accPermission.getUrl();
            if (StringUtils.isEmpty(url)) {
                continue;
            }

            if (antPathMatcher.match(url, requestUrl)) {
                return accPermission;
            }

        }
        return null;
    }

    @Override
    public int deleteByMenuId(Long id) {
        Preconditions.checkArgument(id != null, "菜单ID不能为空");

        // 删除角色权限表数据
        Example example = new Example(AccPermission.class);
        Example.Criteria criteria= example.createCriteria();
        criteria.andEqualTo("menuId", id);
        List<AccPermission> accPermissions = accPermissionMapper.selectByExample(example);

        if (PublicUtil.isNotEmpty(accPermissions)) {
            List<Long> deleteIdList = new ArrayList<>();
            for (AccPermission temp : accPermissions) {
                deleteIdList.add(temp.getPermissionId());
            }
            accRolePermissionService.batchDeleteByPermissionIdList(deleteIdList);
        }

        return accPermissionMapper.deleteByMenuId(id);
    }

    @Override
    public List<AccPermission> listPermissionListByMenus(List<AccMenu> accMenus) {
        return accPermissionMapper.listPermissionListByMenus(accMenus);
    }
}
